home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-06-09 | 9.1 KB | 350 lines | [TEXT/CWIE] |
- // Copyright (C) 1999 Eric Roccasecca. All rights reserved.
-
- #include "X_Ray_Priv.h"
-
-
- X_Ray_AppRecHandle RememberApp (void)
- {
- X_Ray_AppRecHandle curApp, newApp;
- ProcessSerialNumber curSerialNum;
- OSErr err;
- ProcessInfoRec info;
-
- // first go see if app already exists in chain just to be safe
- curApp = GetCurrentAppRec();
- if (curApp) // this app is already in the list, don't bother remembering it again
- return nil;
-
- err = GetCurrentProcess (&curSerialNum);
-
- // find end of app list
- if (gCommRec.appList)
- {
- curApp = gCommRec.appList;
- while ((*curApp)->nextApp) // walk to end of app list
- curApp = (*curApp)->nextApp;
- }
- else
- curApp = nil;
-
- newApp = (X_Ray_AppRecHandle)NewHandleSysClear (sizeof(X_Ray_AppRec)); // create new appRec in system heap
- if (newApp)
- {
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = (*newApp)->name;
- info.processAppSpec = nil;
- err = GetProcessInformation (&curSerialNum, &info);
-
- (*newApp)->appSerialNum = curSerialNum;
- (*newApp)->mode = info.processMode;
- (*newApp)->previousApp = curApp;
- if (curApp)
- (*curApp)->nextApp = newApp; // append to end of app list
- else
- gCommRec.appList = newApp; // no apps, so start new list
- return newApp;
- }
-
- return nil;
- }
-
-
- void ForgetApp (void)
- {
- X_Ray_AppRecHandle curApp, deletedApp;
- ProcessSerialNumber curPSN;
- OSErr err;
- Boolean sameApp;
-
- GetCurrentProcess (&curPSN);
-
- curApp = gCommRec.appList;
- while (curApp != nil)
- {
- err = SameProcess (&(*curApp)->appSerialNum, &curPSN, &sameApp);
- if (sameApp)
- {
- deletedApp = curApp;
-
- // fix app list
- if ((*deletedApp)->nextApp)
- (*(*deletedApp)->nextApp)->previousApp = (*deletedApp)->previousApp;
- if ((*deletedApp)->previousApp)
- (*(*deletedApp)->previousApp)->nextApp = (*deletedApp)->nextApp;
-
- if (deletedApp == gCommRec.appList)
- gCommRec.appList = (*deletedApp)->nextApp;
-
- curApp = (*deletedApp)->nextApp;
-
- PurgeDeadAppWindows (deletedApp);
-
- DisposeHandle ((Handle)deletedApp);
-
- return;
- }
- else
- curApp = (*curApp)->nextApp;
- }
- }
-
-
- // see if an app has already called InitWindows
- // apps shouldn't call InitWindows more than once, but this is just to be safe
- Boolean AppInitWindowsState (void)
- {
- X_Ray_AppRecHandle curApp;
-
- curApp = GetCurrentAppRec();
- if (!curApp)
- return false; // no app rec found, oops!
-
- if ((*curApp)->appWindowsAreInited)
- return false; // app is already InitWindowed so don't bother doing InitWindow handling
- else
- {
- (*curApp)->appWindowsAreInited = true;
- return true; // app is not InitWindowed so do the handling
- }
- }
-
-
- X_Ray_AppRecHandle GetCurrentAppRec (void)
- {
- ProcessSerialNumber curSerialNum;
- X_Ray_AppRecHandle curApp;
- OSErr err;
- Boolean sameProcess;
-
- CleanAppList();
- err = GetCurrentProcess (&curSerialNum);
- curApp = gCommRec.appList;
- while (curApp != nil)
- {
- HLock ((Handle)curApp);
- err = SameProcess (&curSerialNum, &(*curApp)->appSerialNum, &sameProcess);
- HUnlock ((Handle)curApp);
-
- if (sameProcess)
- return curApp;
- curApp = (*curApp)->nextApp;
- }
-
- return nil;
- }
-
-
- // walk app list to get original trap values
- UniversalProcPtr GetLocalTrap (long trapNum)
- {
- X_Ray_AppRecHandle curApp;
-
- curApp = GetCurrentAppRec();
- if (curApp)
- {
- switch (trapNum)
- {
- case _InitWindows:
- return (*curApp)->appInitWindows;
- break;
- default:
- break;
- }
- }
-
- return nil;
- }
-
-
- // walk app list to get appRec for remembering global window
- void SetAppGlobalWindow (WindowPtr theAppGWindow)
- {
- X_Ray_AppRecHandle curApp;
-
- curApp = GetCurrentAppRec();
- if (curApp)
- {
- if ((*curApp)->appGlobalWindow == nil)
- (*curApp)->appGlobalWindow = (LayerPtr)theAppGWindow;
- // JUST CHANGED
- else
- curApp = (*curApp)->nextApp;
- }
- }
-
-
- // removes expired apps from app list and their associated windows
- // this may not be needed because of the patch of CleanupApplication()
- // but I just can't bring myself to remove this yet
- void CleanAppList()
- {
- X_Ray_AppRecHandle curApp, deletedApp;
- ProcessInfoRec info;
- OSErr err;
-
- curApp = gCommRec.appList;
- while (curApp != nil)
- {
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = nil;
- info.processAppSpec = nil;
- err = GetProcessInformation (&(*curApp)->appSerialNum, &info);
-
- if (err == procNotFound)
- {
- deletedApp = curApp;
-
- // fix app list
- if ((*deletedApp)->nextApp)
- (*(*deletedApp)->nextApp)->previousApp = (*deletedApp)->previousApp;
- if ((*deletedApp)->previousApp)
- (*(*deletedApp)->previousApp)->nextApp = (*deletedApp)->nextApp;
-
- if (deletedApp == gCommRec.appList)
- gCommRec.appList = (*deletedApp)->nextApp;
-
- curApp = (*deletedApp)->nextApp;
-
- PurgeDeadAppWindows (deletedApp);
-
- DisposeHandle ((Handle)deletedApp);
- }
- else
- curApp = (*curApp)->nextApp;
- }
- }
-
-
- // removes transparent or clear windows belonging to an app that has died and didn't clean up after itself
- void PurgeDeadAppWindows (X_Ray_AppRecHandle deletedApp)
- {
- X_Ray_WindowHandle deadWin;
-
- deadWin = gCommRec.tsmWindowList; // check the TSM list for app owned window
- while (deadWin)
- {
- if ((*deadWin)->owner == deletedApp)
- X_Ray_DisposeWindow (deadWin);
- deadWin = (*deletedApp)->windowList;
- }
-
- // this may be removed if applications have to take responsibility for providing enough memory for transparent windows
- // for now though X-Ray manages this memory itself
- deadWin = (*deletedApp)->windowList;
- while (deadWin)
- {
- X_Ray_DisposeWindow (deadWin);
- deadWin = (*deletedApp)->windowList;
- }
- }
-
-
- // reorders an app in the app list
- RgnHandle ReorderApp (X_Ray_AppRecHandle theApp, short reorderMethod)
- {
- X_Ray_AppRecHandle curApp;
- RgnHandle updateRgn = nil, curVisRgn = nil;
- X_Ray_WindowHandle curTransWindow;
- GrafPtr origPort;
- WindowPtr curWindow;
-
- curApp = gCommRec.appList;
- switch (reorderMethod) {
- case kROMethod_BringToFront:
- if (theApp == curApp) // app is already front most
- break;
-
- updateRgn = NewRgn();
- curVisRgn = NewRgn();
-
- GetPort (&origPort);
- curTransWindow = (*curApp)->windowList;
- while (curTransWindow)
- {
- // accumulate a region of all transwind visRgns
- CopyRgn ((*curTransWindow)->theWindow->visRgn, curVisRgn);
- SetPort ((*curTransWindow)->theWindow); // to get proper coordinate system
- X_Ray_LocalToGlobalRgn (curVisRgn);
- UnionRgn (updateRgn, curVisRgn, updateRgn);
-
- curTransWindow = (*curTransWindow)->nextWindow;
- }
-
- // see where accumulated visRgns intersect the app comming forward
- // and invalidate the intersections
- if (!EmptyRgn (updateRgn))
- {
- curWindow = GetFirstLayerWindow ((LayerPtr)(*theApp)->appGlobalWindow);
- while (curWindow)
- {
- SetPort (curWindow); // to get proper coordinate system
- X_Ray_GlobalToLocalRgn (updateRgn);
- SectRgn (curWindow->visRgn, updateRgn, curVisRgn);
- if (!EmptyRgn (curVisRgn))
- InvalRgn (curVisRgn);
- X_Ray_LocalToGlobalRgn (updateRgn);
-
- curWindow = (WindowPtr)((WindowPeek)curWindow)->nextWindow;
- }
- SetPort (origPort);
- }
-
- if ((*theApp)->nextApp)
- (*(*theApp)->nextApp)->previousApp = (*theApp)->previousApp;
- if ((*theApp)->previousApp)
- (*(*theApp)->previousApp)->nextApp = (*theApp)->nextApp;
- if (gCommRec.appList)
- (*(gCommRec.appList))->previousApp = theApp;
- (*theApp)->nextApp = gCommRec.appList;
- (*theApp)->previousApp = nil;
- gCommRec.appList = theApp;
-
- DisposeRgn (curVisRgn);
-
- //DebugStr ("\pnew front app…");
- //DebugStr ((*theApp)->name);
- break;
-
- // I commented this out because this is actually handled when the app beind the hiding app is brought to the foreground
- // Once again, I just can't bring myself to delete this code yet
- /* case kROMethod_ShowHide:
- if (switchWindow == (*theApp)->appGlobalWindow) // no need to move an app behind itself, this will probably never occur
- break;
-
- while (true)
- {
- curTransWindow = X_Ray_GetWindowRec (curWindow);
- if (curTransWindow) // remember most recently found transparent window in front to back order
- foundWindow = curTransWindow;
- if (curWindow == switchWindow) // found the window to go behind, can be nil which means window is being moved to the end of list
- {
- if ((foundWindow != theApp) && ((*foundWindow)->nextWindow != theApp) && (foundWindow != nil)) // don't operate on the same window of course
- {
- if (((*theApp)->windowKind&kTSMWindow) && (gCommRec.tsmWindowList == theApp)) // update list heads if necessary
- gCommRec.tsmWindowList = (*foundWindow)->nextWindow;
- else if ((*((*theApp)->owner))->windowList == theApp)
- (*((*theApp)->owner))->windowList = (*theApp)->nextWindow;
-
- if ((*theApp)->nextWindow)
- (*(*theApp)->nextWindow)->previousWindow = (*theApp)->previousWindow;
- (*theApp)->nextWindow = (*foundWindow)->nextWindow;
- if ((*theApp)->nextWindow)
- (*(*theApp)->nextWindow)->previousWindow = theApp;
- (*foundWindow)->nextWindow = theApp;
- (*theApp)->previousWindow = foundWindow;
- }
- break;
- }
- if (curWindow == nil) // end of chain reached
- break;
- curWindow = (WindowPtr)((WindowPeek)curWindow)->nextWindow;
- }
- break;
- */
- default:
- break;
- }
-
- return updateRgn;
- }
-